/*
 * @Autor: chenjie
 * @Date: 2023-03-06 15:36:10
 * @LastEditors: chenjie
 * @LastEditTime: 2023-03-13 15:52:02
 */
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function Square(props) {
    return (
        <button
            className={props.class + " square"}
            onClick={props.onClick}
        >
            {props.value}
        </button>
    )
}

class Board extends React.Component {
    renderSquare(i, index, result) {
        return (
            <Square
                value={this.props.squares[i]}
                key={index}
                class={result && result.includes(i) ? 'winner' : ''}
                onClick={() => this.props.onClick(i)}
            />
        );
    }

    render() {
        // ---获取结果-获胜高亮。
        let winnerResult = calculateWinner(this.props.squares, 'result')
        // ---获取结果-平局弹窗。
        if (!winnerResult && !this.props.squares.includes(null)) {
            setTimeout(() => {
                alert('平局哦~')
            }, 500)
        }
        //---- 两个循环构建棋盘start 
        let createChessboardData = {}
        const rowNums = (rowNum, cellNum) => {
            let cellIndex = 0;
            for (var i = 0; i < rowNum; i++) {
                createChessboardData[i] = []
                if (!createChessboardData[i] || createChessboardData[i].length < rowNum) {
                    for (var l = cellIndex; l < cellNum; l++) {
                        if (createChessboardData[i].length === rowNum) break
                        createChessboardData[i].push(l)
                        cellIndex++
                    }
                }
            }
        }
        rowNums(3, 9) // 额外说明，可动态添加棋盘面积，行数需要和格子总数是整倍数关系如9/3 12/3 也可以是16/4 25/5，两者为次方差时为正方形反之为长方形
        const createChessboardArr = Object.values(createChessboardData)
        const createChessboard = createChessboardArr.map((item, i) => {
            let createSquare = item.map((s, i) => {
                return this.renderSquare(s, i, winnerResult)
            })
            return (
                <div key={i} className="board-row">{createSquare}</div>
            )
        })
        //---- 两个循环构建棋盘end

        return (
            <div>
                {createChessboard}
            </div>
        );
    }
}

class Game extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            history: [{
                squares: Array(9).fill(null),
                coordinateText: '' // 构建显示坐标
            }],
            rootData: [],
            winnerCoord: [],
            xIsNext: true,
            stepNumber: 0,
            coordinates: {
                0: '1-1',
                1: '2-1',
                2: '3-1',
                3: '1-2',
                4: '2-2',
                5: '3-2',
                6: '1-3',
                7: '2-3',
                8: '3-3',
            }
        }
    }

    handleClick(i) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1]
        const squares = current.squares.slice()
        let coordinateText = current.coordinateText
        if (calculateWinner(squares) || squares[i]) {
            return
        }
        squares[i] = this.state.xIsNext ? 'X' : 'O'
        coordinateText = this.state.coordinates[i]
        let arr = history.concat([{
            squares: squares,
            coordinateText: coordinateText
        }])
        this.setState({
            history: arr,
            rootData: arr,
            xIsNext: !this.state.xIsNext,
            stepNumber: history.length,
        })
    }

    jumpTo(step) {
        this.setState({
            stepNumber: step,
            xIsNext: (step % 2) === 0
        })
    }

    //---升降序
    handleAscOrDes(type) {
        const current = this.state.history[this.state.stepNumber]
        const rootData = this.state.rootData
        let dataObj = {}
        const activeDataStr = JSON.stringify(current)
        rootData.forEach((h, index) => {
            dataObj[index] = h
        })
        let dataArr = Object.keys(dataObj)
        dataArr.sort((a, b) => {
            return type === 'asc' ? a - b : b - a
        })
        let targetArr = []
        let index = 0;
        while (index < dataArr.length) {
            targetArr.push(dataObj[dataArr[index]])
            index++
        }
        let rootStep = 0
        while (rootStep < targetArr.length) {
            let str = JSON.stringify(targetArr[rootStep])
            if (activeDataStr === str) {
                this.setState({
                    stepNumber: rootStep,
                    history: targetArr
                })
            }
            rootStep++
        }
    }
    // --升降end

    render() {
        const history = this.state.history;
        const current = history[this.state.stepNumber]
        const winner = calculateWinner(current.squares)
        const stepNumber = this.state.stepNumber
        const moves = history.map((step, move) => {
            const desc = move || history[move].coordinateText ?
                'Go to move #' + move + '坐标为' + history[move].coordinateText :
                'Go to game start';
            return (
                // 加粗当前显示
                <li key={move} className={stepNumber == move ? 'active' : ''}>
                    <button onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            )
        })

        let status;
        if (winner) {
            status = `Winner: ${winner}`
        } else {
            status = `Next player: ${this.state.xIsNext ? 'X' : 'O'}`
        }

        return (
            <div className="game">
                <div className="game-board">
                    <Board
                        squares={current.squares}
                        onClick={(i) => this.handleClick(i)}
                    />
                </div>
                <div className="game-info">
                    <div>{status}</div>
                    <div className='asc'>
                        <Square
                            value={'升序'}
                            onClick={() => this.handleAscOrDes('asc')}
                        />
                    </div>
                    <div className='des'>
                        <Square
                            value={'倒序'}
                            onClick={() => this.handleAscOrDes('des')}
                        />
                    </div>
                    <ol>{moves}</ol>
                </div>
            </div>
        );
    }
}

// ========================================
const calculateWinner = (squares, returnResult = 'person') => {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            // 返回获胜结果
            return returnResult === 'person' ? squares[a] : lines[i];
        }
    }
    return null;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Game />);
